<?php
/**
 * 业务流程
 * 用户支付后，如果是在线上，则在用户确认收货后，走分红系统，如果是线下，直接走分红系统
 * 需要参数：1.服务商号，2.商户号，3.代理账号（可无），4.参与分账方账号，5.分账方分账金额，
 * 技术细节：
 *        1.在单次分账的时候，出资方用户分红走退款模式，
 *        2.在分账过程中，出款方用户多次参与分红
 *
 * 微信单次分账接口：https://api.mch.weixin.qq.com/secapi/pay/profitsharing
 * 微信多次分账接口：https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing
 * 参数：
 *     商户号：          mch_id     微信支付分配的商户号
 *     子商户号：        sub_mch_id 微信支付分配的子商户号
 *     公众账号ID：      appid      微信分配的公众账号ID
 *     子商户公众账号ID： sub_appid  微信分配的子商户公众账号ID
 *     随机字符串：      nonce_str
 *     签名：           sign
 *     签名类型：        sign_type（目前只支持HMAC-SHA256）
 *     微信订单号：      transaction_id 微信支付订单号
 *     商户分账单号：    out_order_no  服务商系统内部的分账单号，在服务商系统内部唯一（单次分账、多次分账、完结分账应使用不同的商户分账单号），同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@
 *     分账接收方列表：   receivers
 *
 */

namespace app\common\library\wechat;
use app\common\exception\BaseException;
use app\common\library\wechat\WxSign;
use app\common\library\wechat\WxCurl;
use app\common\model\Wxapp as WxappModel;
use app\common\library\MysicLog;
use app\common\service\Order;
use org\RabbitMQ;
use app\common\model\divide\System;
use think\Exception;


class Abonus extends WxBase
{

    // 微信支付配置
    private $config;
    private $curl;
    private $sign ;
    private $log;
    private $order;
    private $dividendOrder;
    private $wxResponse;
    /**
     * 构造函数
     * WxPay constructor.
     * @param $wxappId int
     */
    public function __construct($wxappId = null)
    {
        parent::__construct();
        $this->log = MysicLog::instance();
        $wxappId && $this->config =$this->wxConfig($wxappId);
        $this->sign = new WxSign();//签名类
        $this->curl = new WxCurl();//签名类

    }

    public function getResponse()
    {
        return $this->wxResponse;
    }

    protected function log($pre,$data = null)
    {
        $fileName = 'fenhong-'.date('Ymd', time()).'.log';
        if(!file_exists($fileName)) {
            if($data) {
                $data = is_array($data) ? json_encode($data) : $data;
                file_put_contents($fileName,  $pre . $data .  PHP_EOL, FILE_APPEND);
            } else {
                file_put_contents($fileName,  $pre .  PHP_EOL, FILE_APPEND);
            }
            chmod($fileName, 0766);
        }else {
            if($data) {
                $data = is_array($data) ? json_encode($data) : $data;
                file_put_contents($fileName,  $pre . $data .  PHP_EOL, FILE_APPEND);
            } else {
                file_put_contents($fileName,  $pre .  PHP_EOL, FILE_APPEND);
            }
        }
    }

    public function setUserOrder($order)
    {
        if(!$order->getData() || empty($order->getData())) {
            throw new Exception('setOrder - 订单信息为空');
        }
        $this->config = $this->wxConfig($order->wxapp_id);
        $this->order = $order;
        return $this;
    }

    public function setDividendOrder($order)
    {
        $this->dividendOrder = $order;
        return $this;
    }

    /**
     * @function 发起请求所必须的配置参数
     * @return mixed
     * @param $wxappId int
     */
    public function wxConfig($wxappId)
    {
        $wxConfigs = WxappModel::getWxappCache($wxappId);
        $log = [
            'wxapp_id' => $wxConfigs['wxapp_id'],
            'app_id' => $wxConfigs['app_id'],
            'app_secret' => $wxConfigs['app_secret'],
            'mchid' => $wxConfigs['mchid'],
            'apikey' => $wxConfigs['apikey'],
            'finish_time' => $wxConfigs['finish_time'],
            'wxapp_name' => $wxConfigs['wxapp_name'],
            'is_recycle' => $wxConfigs['is_recycle'],
            'is_delete' => $wxConfigs['is_delete']
        ];
        $this->log->info($log, '微信分账接口必须的配置参数');
        //获取证书

        if (empty($wxConfigs['cert_pem']) || empty($wxConfigs['key_pem'])) {
            throw new BaseException(['msg' => '请先到后台小程序设置填写微信支付证书文件']);
        }

        $wxConfig['sub_mch_id'] = $wxConfigs['mchid'];
        $wxConfig['sub_app_id'] = $wxConfigs['app_id'];
        $wxConfig['md5_key']    = $wxConfigs['apikey'];
        // cert目录
        $filePath = __DIR__ . '/cert/' . $wxConfigs['wxapp_id'] . '/';
        $wxConfig['certPem']    = $filePath . 'cert.pem';
        $wxConfig['keyPem']     = $filePath . 'key.pem';
        $this->log->info($wxConfig, '微信支付配置参数');
        $this->config = $wxConfig;
        return $wxConfig;
    }

    public function addReceivers($receiver):bool
    {
        $this->log->info($this->config, '添加分帐人 - 微信接口配置参数');
        //1.接收分账账户
        $receiver = json_encode($receiver,JSON_UNESCAPED_UNICODE);
        //商户直连模式
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'receiver'=>$receiver
        );

        $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log->info($postArr, '添加分帐人接口入参');
        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver';
        $postXML = $this->toXml($postArr);
        $curl_res = $this->curl->post($url,$postXML);

        // 请求失败
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信添加分账方api请求失败']);
        }
        $ret = $this->toArray($curl_res);
        $this->log->info($ret, '添加分帐人接口返回值');
        $this->wxResponse = $ret;
        $responseSign = $ret['sign'] ?? '';
        if(!$responseSign) {
            return false;
        }
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info([
            '本地签名' => $localSign,
            '返回值签名' => $responseSign
        ], '签名对比');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS') {
            throw new Exception($ret['err_code_des']);
        }
        return true;
    }



    /*******************统一分账内容**************************************/
    /**
     * 获取分账用户接口
     * @param $order array 订单信息
     * @throws BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function getDivideList($order){
        //获取系统分账
        $system[]=db('divide_system')->where(['order_no'=>$order['order_no'],'transaction_id'=>$order['transaction_id'],'wxapp_id'=>$order['wxapp_id']])->field('type,account,amount,description')->find();
        //获取商户分账
        // $store[]=db('divide_store')->where(['order_no'=>$order['order_no'],'transaction_id'=>$order['transaction_id'],'wxapp_id'=>$order['wxapp_id']])->field('type,account,amount,description')->find();
        //获取店员分账
        $storeStaff=collection(db('divide_store_clerk')->where(['order_no'=>$order['order_no'],'transaction_id'=>$order['transaction_id'],'wxapp_id'=>$order['wxapp_id']])->field('type,account,amount,description')->select())->toArray();
        //获取用户分账
        //  $userList=collection(db('divide_receive')->where(['order_no'=>$order['order_no'],'transaction_id'=>$order['transaction_id'],'wxapp_id'=>$order['wxapp_id']])->field('type,account,amount,description')->select())->toArray();
        //$divideList=array_merge($system,$store,$userList,$storeStaff);
        //商户直连，不给商户分
        $divideList=array_merge($system,$storeStaff);
        // $divideList=array_merge($system);
        $list=[];
        foreach ($divideList as $key=>$value){
            $list[$key]['type']=$value['type'];
            $list[$key]['account']=$value['account'];
            $list[$key]['amount']=$value['amount']*100;
            $list[$key]['description']=$value['description'];
        }
        if(count($list)==1){

            $reault=$this->profitSharing($order,$list);

            return  $reault;
        }else{

            $reault=$this->multiProfitSharing($order,$list);

            return  $reault;
        }

    }
    /*******************统一分账内容**************************************/


    /**
     * @function 请求多次分账接口
     * @param $orders array 待分账订单
     * @param $userList array 分账接收方
     *
     * @return array
     * @throws BaseException
     */
    public function multiProfitSharing($orders,$userList)
    {
        if(empty($orders)){
            throw new BaseException(['msg' => "微信分账：没有待分帐订单", 'code' => -10]);
        }
        if(empty($userList)){
            throw new BaseException(['msg' => "微信分账：接收分账账户为空", 'code' => -10]);
        }
        //1.设置分账账号

        $receivers = json_encode($userList,JSON_UNESCAPED_UNICODE);
        //2.生成签名

        //商户直连模式
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'transaction_id'=>$orders['transaction_id'],
            'out_order_no'=>$orders['order_no'],
            'receivers'=>$receivers,
        );
        $sign =  $this->sign->getSign($postArr,  'HMAC-SHA256', $this->config['md5_key']);
        $postArr['sign'] = $sign;

        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing';
        $postXML = $this->toXml($postArr);

        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );

        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
        // 请求失败
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信分账api请求失败']);
        }
        $this->doLogs("多次分账结果: " . $curl_res);
        $ret = $this->toArray($curl_res);
        if($ret['return_code']=='SUCCESS' and $ret['result_code']=='SUCCESS')
        {
            //更新系统平台状态
            db('divide_system')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>1,'update_time'=>time()]);
            //更新商户代言人状态
            //  $this->storeStaffUpdateAll($orders,1,'分账成功');
            //更新用户状态
            // $this->userUpdateAll($orders,1,'分账成功');

        }else{
            db('divide_system')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>2,'fail_reason'=>$ret['err_code_des'],'update_time'=>time()]);

            //更新商户代言人状态
            // $this->storeStaffUpdateAll($orders,2,$ret['err_code_des']);
            //更新用户状态
            //$this->userUpdateAll($orders,2,$ret['err_code_des']);

        }
        return json_encode($ret);
    }



    public function profitSharing($orders,$userList)
    {

        if(empty($orders)){
            throw new BaseException(['msg' => "微信分账：没有待分帐订单", 'code' => -10]);
        }
        if(empty($userList)){
            throw new BaseException(['msg' => "微信分账：接收分账账户为空", 'code' => -10]);
        }
        $totalCount = count($userList);
        $receivers = json_encode($userList,JSON_UNESCAPED_UNICODE);
        //商户直连模式
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'out_order_no'=>$orders['order_no'],
            'transaction_id'=>$orders['transaction_id'],
            'sign_type'=>'HMAC-SHA256',
            'receivers'=>$receivers,
        );

        $sign =$this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;

        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';
        $postXML = $this->toXml($postArr);

        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );
        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);

        // 请求失败
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信分账api请求失败']);
        }
        $this->doLogs("单次分账结果: " . $curl_res);
        $ret = $this->toArray($curl_res);
        if($ret['return_code']=='SUCCESS' && $ret['result_code']=='SUCCESS')
        {
            //更新系统平台状态
            db('divide_system')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>1,'update_time'=>time()]);
            //更新商户代言人状态
            // $this->storeStaffUpdateAll($orders,1,'分账成功');
            //更新用户状态
            // $this->userUpdateAll($orders,1,'分账成功');

        }else{
            db('divide_system')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>2,'fail_reason'=>$ret['err_code_des'],'update_time'=>time()]);
            //更新商户代言人状态
            // $this->storeStaffUpdateAll($orders,2,$ret['err_code_des']);
            //更新用户状态
            // $this->userUpdateAll($orders,2,$ret['err_code_des']);
//            return  false;
        }

        return json_encode($ret);
    }

    public function query($order)
    {
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],
            'sub_mch_id'=>$this->config['sub_mch_id'],
            'transaction_id'=>$order['transaction_id'],
            'out_order_no'=>$order['order_no'],
            'nonce_str'=>md5($order['order_no'].time() . rand(1000, 9999)),
        );

        $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;

        //2.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingquery';
        $postXML = $this->toXml($postArr);
        $curl_res = $this->curl->post($url,$postXML);
        // $curl_res =$this->post($url,$postXML);
        return $this->toArray($curl_res);
    }

    public function dividendApplyQueryForTest($orderNo, $transactionId)
    {
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],
            'transaction_id'=> $transactionId,
            'out_order_no'=> $orderNo,
            'nonce_str'=>md5($orderNo . time() . rand(1000, 9999)),
        );
        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256', $this->config['md5_key']);
        $postArr['sign'] = $sign;
        //2.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingquery';
        $postXML = $this->toXml($postArr);
        $curl_res = $this->curl->post($url,$postXML);
        $ret = $this->toArray($curl_res);
        echo '分账结果查询接口返回值' , PHP_EOL;
        print_r($ret);
        $this->log->info($ret, '分账结果查询接口返回值');
        $responseSign = $ret['sign'] ?? '';
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        echo $responseSign, ' - 微信接口返回值的签名', PHP_EOL;
        echo $localSign, ' - 微信返回值生成的本地签名', PHP_EOL;
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS') {
            throw new Exception($ret['err_code_des']);
        }
        if($ret['result_code'] == 'SUCCESS') {
            if($ret['status'] == 'CLOSED'){
                throw new Exception($ret['close_reason']);
            }
            if($ret['status'] != 'FINISHED') {
                $ret = $this->dividendApplyQueryForTest($orderNo, $transactionId);
                if($ret) {
                    return true;
                }
            }
        }
        return true;
    }

    public function dividendApplyQuery()
    {
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],
            'transaction_id'=>$this->order->transaction_id,
            'out_order_no'=>$this->order->order_no,
            'nonce_str'=>md5($this->order->order_no . time() . rand(1000, 9999)),
        );
        $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;

        //2.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingquery';
        $postXML = $this->toXml($postArr);
        $curl_res = $this->curl->post($url,$postXML);
        $ret = $this->toArray($curl_res);
        $this->log->info($ret, '分账结果查询接口返回值');
        $responseSign = $ret['sign'] ?? '';
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info($responseSign, '微信接口返回值的签名');
        $this->log->info($localSign, '微信返回值生成的本地签名');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS') {
            throw new Exception($ret['err_code_des']);
        }
        if($ret['result_code'] == 'SUCCESS') {
            if($ret['status'] == 'CLOSED'){
                throw new Exception($ret['close_reason']);
            }
            if($ret['status'] != 'FINISHED') {
                return false;
            }
        }
        return true;
    }

    public function dividendOver($description): bool
    {
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],
            'appid'=>$this->config['sub_app_id'],
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'transaction_id'=>$this->order->transaction_id,
            'out_order_no'=>$this->order->order_no,
            'description'=> $description,
        );

        $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log->info($postArr, '调用微信订单分账完结接口入参');
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish';
        $postXML = $this->toXml($postArr);
        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );

        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
        $ret = $this->toArray($curl_res);
        $this->wxResponse = $ret;
        $this->log->info($ret, '微信接口返回值');
        $responseSign = $ret['sign'] ?? '';
        if(!$responseSign) {
            return false;
        }
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info($responseSign, '微信接口返回值的签名');
        $this->log->info($localSign, '微信返回值生成的本地签名');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS' && !in_array($ret['err_code'], ['ORDER_NOT_READY', 'FREQUENCY_LIMITED'])) {
            throw new Exception($ret['err_code_des']);
        }
        if($ret['result_code'] != 'SUCCESS' && in_array($ret['err_code'], ['ORDER_NOT_READY', 'FREQUENCY_LIMITED'])){
            sleep(1);
            $ret = $this->dividendOver($description);
            if($ret) {
                return true;
            }
        }

        return true;
    }

    public function receiverAdd()
    {
        $ret = $this->addReceiver();
        $this->log->info($ret, '调用微信添加分帐人接口返回值');
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS') {
            throw new Exception($ret['err_code_des']);
        }
        return true;
    }

    public function addReceiver()
    {
        //1.接收分账账户
        $receiver = array(
            'type'=>'MERCHANT_ID',
            'account'=>'1551787381',
            'name'=>'陕西龙达天创信息科技有限公司',
            'relation_type'=>'SERVICE_PROVIDER',
        );

        $receiver = json_encode($receiver,JSON_UNESCAPED_UNICODE);


        //商户直连模式
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'receiver'=>$receiver
        );

        $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log->info($postArr, '调用微信添加分账接收人入参');
        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver';
        $postXML = $this->toXml($postArr);
        $curl_res = $this->curl->post($url,$postXML);

        // 请求失败
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信添加分账方api请求失败']);
        }
        $ret = $this->toArray($curl_res);
        $this->log->info($ret, '微信接口返回值');
        $responseSign = $ret['sign'] ?? '';
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info($responseSign, '微信接口返回值的签名');
        $this->log->info($localSign, '微信返回值生成的本地签名');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        return $ret;
    }


    public function removeReceiver($account, $type)
    {
        //1.接收分账账户
        $receiver = array(
            'type'=>$type,
            'account'=>$account
        );
        $receiver = json_encode($receiver,JSON_UNESCAPED_UNICODE);
        //2.生成签名
        $postArr = array(
            'appid'=>$this->config['sub_app_id'],
            'mch_id'=>$this->config['sub_mch_id'],
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'receiver'=>$receiver
        );
        $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log->info($postArr, '删除分账接收人接口入参');
        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingremovereceiver';
        $postXML = $this->toXml($postArr);

        $curl_res = $this->curl->post($url,$postXML);
        $this->doLogs("移除分账方: " . $curl_res);
        $ret = $this->toArray($curl_res);
        $this->wxResponse = $ret;
        $this->log->info($ret, '删除分账接收人接口返回值');
        $responseSign = $ret['sign'] ?? '';
        if(!$responseSign){
            return false;
        }
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info([
            '本地签名' => $localSign,
            '返回值签名' => $responseSign
        ], '签名对比');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        return $ret;
    }


    /**
     * @function 完结分账
     * @param $order array 分账订单
     * @param $description string 完结分账描述
     * @return array|false
     * @throws BaseException
     */
    public function finish($order,$description='分账完结')
    {
        file_put_contents("notify1.log",  '分账完结111结果'.json_encode($order).  "\n", FILE_APPEND);
        $ret = array();
        if(!empty($order))
        {
            //1.签名
//            $postArr = array(
//                'mch_id'=>$this->config['mch_id'],
//                'sub_mch_id'=>$this->config['sub_mch_id'],
//                'appid'=>$this->config['app_id'],
//                'nonce_str'=>md5(time() . rand(1000, 9999)),
//                'transaction_id'=>$order['transaction_id'],
//                'out_order_no'=>$order['order_no'],
//                'description'=>$description,
//            );
            $postArr = array(
                'mch_id'=>$this->config['mch_id'],
                'appid'=>$this->config['app_id'],
                'nonce_str'=>md5(time() . rand(1000, 9999)),
                'transaction_id'=>$order['transaction_id'],
                'out_order_no'=>'b'.$order['order_no'],
                'description'=>$description,
            );

            $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
            $postArr['sign'] = $sign;
            file_put_contents("notify1.log",  '分账完结222结果'. $postArr.  "\n", FILE_APPEND);
            //2.请求
            $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish';
            $postXML = $this->toXml($postArr);
            $opts = array(
                CURLOPT_HEADER    => 0,
                CURLOPT_SSL_VERIFYHOST    => false,
                CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
                CURLOPT_SSLCERT   => $this->config['certPem'],
                CURLOPT_SSLKEY    => $this->config['keyPem'],
            );

            $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
            file_put_contents("notify1.log",  '分账完结333结果'. $curl_res.  "\n", FILE_APPEND);
            $ret = $this->toArray($curl_res);
        }
        return $ret;
    }


    /**
     * 分账回退
     * @param $userOpenid string 用户opendId
     * @param $order_no   int 订单号
     * @param $amount    int 返回金额
     * @return array
     * @throws \Exception
     */

    public function profitSharingReturn($userOpenid,$order_no,$amount)
    {

        $ret = array();
        if(!empty($userOpenid) || !empty($order_no) || !empty($amount))
        {

            //1.签名
//                $postArr = array(
//                    'appid'=>$this->config['app_id'],
//                    'mch_id'=>$this->config['mch_id'],
//                    'sub_mch_id'=>$this->config['sub_mch_id'],
//                    'sub_appid'=>$this->config['sub_app_id'],
//                    'nonce_str'=>md5(time() . rand(1000, 9999)),
//                    'out_order_no'=>$profitOrder['order_no'].$profitOrder['ticket_no'],
//                    'out_return_no'=>'return_'.$profitOrder['order_no'].$profitOrder['ticket_no'].'_'.$account['account'],
//                    'return_account_type'=>'MERCHANT_ID',
//                    'return_account'=>$account['account'],
//                    'return_amount'=>$account['amount'],
//                    'description'=>'用户退款',
//                    'sign_type'=>'HMAC-SHA256',
//                );
            $postArr = array(
                'mch_id'=>$this->config['sub_mch_id'],
                'appid'=>$this->config['sub_app_id'],
                'nonce_str'=>md5(time() . rand(1000, 9999)),
                'out_order_no'=>$order_no,
                'out_return_no'=>Order::createOrderNo(),
                'return_account_type'=>'MERCHANT_ID',
                'return_account'=>$userOpenid,//回退账户（用户openid）
                'return_amount'=>$amount,//回退金额
                'description'=>'用户退款',
            );
            $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
            $postArr['sign'] = $sign;
            //2.请求
            $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingreturn';
            $postXML = $this->toXml($postArr);

            $opts = array(
                CURLOPT_HEADER    => 0,
                CURLOPT_SSL_VERIFYHOST    => false,
                CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
                CURLOPT_SSLCERT   => $this->config['certPem'],
                CURLOPT_SSLKEY    => $this->config['keyPem'],
            );
            $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
            file_put_contents("notify1.log",  '分账回退结果'. $curl_res.  "\n", FILE_APPEND);
            $ret[] = $this->toArray($curl_res);
        }
        return $ret;
    }


    /**
     * @function 回退结果查询
     * @param $order_no string 本地订单号
     * @param $ticket_no string 本地票号
     * @return array|false
     * @throws BaseException
     */
    public function returnQuery($order_no,$ticket_no)
    {
        $ret = array();
        $profitOrder = pdo_fetch("SELECT * FROM zc_ticket_orders_profitsharing WHERE order_no='{$order_no}' AND ticket_no='{$ticket_no}'");
        if($profitOrder['channel']==1 and $profitOrder['state']==2)
        {
            $accounts = json_decode($profitOrder['profitsharing'],true);
            foreach ($accounts as $account)
            {
                //1.签名
                $postArr = array(
                    'appid'=>$this->config['app_id'],
                    'mch_id'=>$this->config['mch_id'],
                    'sub_mch_id'=>$this->config['sub_mch_id'],
                    'nonce_str'=>md5(time() . rand(1000, 9999)),
                    'out_order_no'=>$profitOrder['order_no'].$profitOrder['ticket_no'],
                    'out_return_no'=>'return_'.$profitOrder['order_no'].$profitOrder['ticket_no'].'_'.$account['account'],
                    'sign_type'=>'HMAC-SHA256',
                );

                $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
                $postArr['sign'] = $sign;

                //2.请求
                $url = 'https://api.mch.weixin.qq.com/pay/profitsharingreturnquery';
                $postXML = $this->toXml($postArr);
                $this->doLogs("returnQuery.postXML: " . $postXML);

                $curl_res = $this->curl->post($url,$postXML);
                $this->doLogs("returnQuery.curl_res: " . $curl_res);

                $ret[] = $this->toArray($curl_res);
            }

        }
        return $ret;
    }


    private function servicesUpdateAll($order,$status,$errDes){
        //更新商户代言人状态
        db('divide_service')->where(['order_no'=>$order['order_no'],'transaction_id'=>$order['transaction_id'],'wxapp_id'=>$order['wxapp_id']])->setField(['status'=>$status,'fail_reason'=>$errDes,'update_time'=>time()]);
    }

    private function storeStaffUpdateAll($order,$status,$errDes){
        //更新商户代言人状态
        db('divide_store_clerk')->where(['order_no'=>$order['order_no'],'transaction_id'=>$order['transaction_id'],'wxapp_id'=>$order['wxapp_id']])->setField(['status'=>$status,'fail_reason'=>$errDes,'update_time'=>time()]);

    }
    private function userUpdateAll($order,$status,$errDes){
        //更新用户状态
        db('divide_store_clerk')->where(['order_no'=>$order['order_no'],'transaction_id'=>$order['transaction_id'],'wxapp_id'=>$order['wxapp_id']])->setField(['status'=>$status,'fail_reason'=>$errDes,'update_time'=>time()]);
    }

    /**
     * 输出xml字符
     * @param $values
     * @return bool|string
     */
    private function toXml($values)
    {
        if (!is_array($values) || count($values) <= 0) {
            return false;
        }

        $xml = "<xml>";
        foreach ($values as $key => $val) {
            //  if (is_numeric($val)) {
            $xml.="<".$key.">".$val."</".$key.">";
            //  } else {
            //     $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            // }
        }
        $xml.="</xml>";

        return $xml;
    }
    /**
     * @function 将xml转为array
     * @param string $xml
     * @return array|false
     * @author xiewg
     */
    public function toArray($xml)
    {
        if (!$xml) {
            return false;
        }
        // 检查xml是否合法
        $xml_parser = xml_parser_create();
        if (!xml_parse($xml_parser, $xml, true)) {
            xml_parser_free($xml_parser);
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $data;
    }

    /**
     * 过滤特殊字符
     * @param string $str
     * @return string
     */
    function xmlSafeStr($str)
    {
        return preg_replace("/[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]/", '', $str);
    }

    public function dividendBalanceQueryForTest($transactionId)
    {
        $postArr = [
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'transaction_id'=> $transactionId,
            'nonce_str'=>md5(time() . rand(1000, 9999)),
        ];
        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256', $this->config['md5_key']);
        $postArr['sign'] = $sign;
        print_r($postArr);
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingorderamountquery';
        $postXML = $this->toXml($postArr);
        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );
        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信分账api请求失败']);
        }
        $ret = $this->toArray($curl_res);
        echo '调用微信分帐申请接口返回值' , PHP_EOL;
        print_r($ret);
        $responseSign = $ret['sign'] ?? '';
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        return true;
    }



    public function dividendApply($dividendOrderList = [])
    {
        if(empty($dividendOrderList)) {
            $dividendOrderList = $this->dividendOrder->where([
                'order_no'=>$this->order->order_no,
                'transaction_id'=> $this->order->transaction_id,
                'wxapp_id'=> $this->order->wxapp_id
            ])->field('type, account, abonus, description')->select();
        }
        $receivers = [];
        foreach($dividendOrderList as $dividendOrder) {
            if(intval(bcmul(strval($dividendOrder->abonus), '100')) > 0) {
                $receivers[] = [
                    'type' => $dividendOrder->type,
                    'account' => $dividendOrder->account,
                    'amount' => intval(bcmul(strval($dividendOrder->abonus), '100')),
                    'description' => $dividendOrder->description
                ];
            }
        }
        if(empty($receivers)) {
            $this->log->error('分账金额为0，不能分账', '分账申请接口调用失败');
            return false;
        }
        $this->log->info($receivers, '待分账接收人列表');
        $receivers = json_encode($receivers,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'out_order_no'=>$this->order->order_no,
            'transaction_id'=>$this->order->transaction_id,
            'sign_type'=>'HMAC-SHA256',
            'receivers'=>$receivers,
        );
        $this->log->info($postArr, '调用微信分账申请接口入参');
        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';
        $postXML = $this->toXml($postArr);
        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );
        sleep(5);// 等待5秒，再调用接口，避免出现ORDER_NOT_READY
        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信分账api请求失败']);
        }
        $ret = $this->toArray($curl_res);
        $this->log->info($ret, '调用微信分帐申请接口返回值');
        $responseSign = $ret['sign'] ?? '';
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info($responseSign, '微信接口返回值的签名');
        $this->log->info($localSign, '微信返回值生成的本地签名');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS' && $ret['err_code'] != 'ORDER_NOT_READY') {
            $ret['err_code_des'] = $ret['err_code_des'] ?? $ret['err_code'];
            throw new Exception($ret['err_code_des']);
        }
        if($ret['result_code'] != 'SUCCESS' && $ret['err_code'] == 'ORDER_NOT_READY'){
            sleep(1);
            $ret = $this->dividendApply($dividendOrderList);
            if($ret) {
                return true;
            }
        }
        return true;
    }

    /**
     * @function 请求单次分账接口
     * @param $orders array 待分账订单
     * @param $userList array 分账接收方
     * @return array
     * @throws BaseException
     */
    public function profitSharings($orders)
    {
        $this->log('10 商家分账逻辑开始...');
        $this->log('10-1 分账订单: ', $orders);
        $system[]=db('divide_system')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->field('type,account,abonus,description')->find();
        $this->log('10-2 分账系统参数: ', $system);
        $list=[];
        foreach ($system as $key=>$value){
            $list[$key]['type']=$value['type'];
            $list[$key]['account']=$value['account'];
           // $list[$key]['amount']=$value['abonus']*100;
            $list[$key]['amount']=(int)(($value['abonus']*1000)/10);
           // $list[$key]['amount']=bcmul($value['abonus'],100);
            $list[$key]['description']=$value['description'];
        }
        if(empty($orders)){
            throw new BaseException(['msg' => "微信分账：没有待分帐订单", 'code' => -10]);
        }
        if(empty($list)){
            throw new BaseException(['msg' => "微信分账：接收分账账户为空", 'code' => -10]);
        }
        $receivers = json_encode($list,JSON_UNESCAPED_UNICODE);
        $this->log('10-3 receivers : ', $receivers);
        //2.生成签名

        //商户直连模式
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'out_order_no'=>$orders['order_no'],
            'transaction_id'=>$orders['transaction_id'],
            'sign_type'=>'HMAC-SHA256',
            'receivers'=>$receivers,
        );

        $sign =$this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log('10-4 postArr: ', $postArr);
        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';
        $postXML = $this->toXml($postArr);
        $this->log('10-5 postArr XML: ', $postXML );
        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );
        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
         file_put_contents("notify2.log",  '分账结果'. $curl_res.  "\n", FILE_APPEND);
        // 请求失败
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信分账api请求失败']);
        }
        $ret = $this->toArray($curl_res);
        $this->log('10-6 CURL调用微信分账接口返回值: ', $ret);
        if($ret['return_code']=='SUCCESS' && $ret['result_code']=='SUCCESS')
        {
            //更新系统平台状态
            db('divide_system')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>1,'update_time'=>time()]);
            //更新服务商状态
            $this->servicesUpdateAll($orders,1,'分账成功');
            //更新商户状态
            db('divide_store')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>1,'update_time'=>time()]);

             //更新订单表的字段
            db('order')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['is_abouns'=>1]);
           
            //更新商户代言人状态
          //  $this->storeStaffUpdateAll($orders,1,'分账成功');
            //更新用户状态
            // $this->userUpdateAll($orders,1,'分账成功');

        }else{
            db('divide_system')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>2,'fail_reason'=>$ret['err_code_des'],'update_time'=>time()]);
            //更新服务商状态
            $this->servicesUpdateAll($orders,2,$ret['err_code_des']);
            //更新商户状态
            db('divide_store')->where(['order_no'=>$orders['order_no'],'transaction_id'=>$orders['transaction_id'],'wxapp_id'=>$orders['wxapp_id']])->setField(['status'=>2,'fail_reason'=>$ret['err_code_des'],'update_time'=>time()]);

            //更新商户代言人状态
           // $this->storeStaffUpdateAll($orders,2,$ret['err_code_des']);
            //更新用户状态
            // $this->userUpdateAll($orders,2,$ret['err_code_des']);
//            return  false;
        }

        return  $ret;
    }
    /**
     * @function 完结分账
     * @param $order array 分账订单
     * @param $description string 完结分账描述
     * @return array|false
     * @throws BaseException
     */
    public function finishs($order)
    {

        $ret = array();
        if(!empty($order))
        {
            //1.签名
            $postArr = array(
                'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
                'appid'=>$this->config['sub_app_id'],//特约商户的appid
                'nonce_str'=>md5(time() . rand(1000, 9999)),
                'transaction_id'=>$order['transaction_id'],
                'out_order_no'=>$order['order_no'],
                'description'=>'分账已完成',
            );

            $sign =  $this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
            $postArr['sign'] = $sign;
            //2.请求
            $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharingfinish';
            $postXML = $this->toXml($postArr);

            $opts = array(
                CURLOPT_HEADER    => 0,
                CURLOPT_SSL_VERIFYHOST    => false,
                CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
                CURLOPT_SSLCERT   => $this->config['certPem'],
                CURLOPT_SSLKEY    => $this->config['keyPem'],
            );

            $curl_res = $this->curl->setOption($opts)->post($url,$postXML);

            $ret = $this->toArray($curl_res);
        }
        return $ret;
    }

     //临时解决解冻商户资金方法
        public function profitTimeSharing($orders)
         {
       
            $list[0]['type']='MERCHANT_ID';
            $list[0]['account']='1551787381';
            $list[0]['amount']=(int)(($orders['pay_price']*0.01)*100);
           // $list[$key]['amount']=bcmul($value['abonus'],100);
            $list[0]['description']='分账给系统服务商';
       
        if(empty($orders)){
            throw new BaseException(['msg' => "微信分账：没有待分帐订单", 'code' => -10]);
        }
        if(empty($list)){
            throw new BaseException(['msg' => "微信分账：接收分账账户为空", 'code' => -10]);
        }
        $receivers = json_encode($list,JSON_UNESCAPED_UNICODE);
        $this->log('10-3 receivers : ', $receivers);
        //2.生成签名

        //商户直连模式
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'out_order_no'=>$orders['order_no'],
            'transaction_id'=>$orders['transaction_id'],
            'sign_type'=>'HMAC-SHA256',
            'receivers'=>$receivers,
        );

        $sign =$this->sign->getSign($postArr, 'HMAC-SHA256',$this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log('10-4 postArr: ', $postArr);
        //3.发送请求
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';
        $postXML = $this->toXml($postArr);
        $this->log('10-5 postArr XML: ', $postXML );
        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );
        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
        // 请求失败
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信分账api请求失败']);
        }
        $ret = $this->toArray($curl_res);
        $this->log('10-6 CURL调用微信分账接口返回值: ', $ret);
      
        return  $ret;
    }

    public function profitSharingApply($receivers, $profitSharingSn, $transactionId): bool
    {
        $receiversJson = json_encode($receivers, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],//特约商户的mchid
            'appid'=>$this->config['sub_app_id'],//特约商户的appid
            'nonce_str'=>md5(time() . rand(1000, 9999)),
            'out_order_no'=> $profitSharingSn,
            'transaction_id'=> $transactionId,
            // 'sign_type'=>'HMAC-SHA256',
            'receivers'=>$receiversJson,
        );
        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256', $this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log->info($postArr, '分账申请接口入参');
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing';
        $postXML = $this->toXml($postArr);
        $opts = array(
            CURLOPT_HEADER    => 0,
            CURLOPT_SSL_VERIFYHOST    => false,
            CURLOPT_SSLCERTTYPE   => 'PEM', //默认支持的证书的类型，可以注释
            CURLOPT_SSLCERT   => $this->config['certPem'],
            CURLOPT_SSLKEY    => $this->config['keyPem'],
        );
        $curl_res = $this->curl->setOption($opts)->post($url,$postXML);
        if (empty($curl_res)) {
            throw new BaseException(['msg' => '微信分账api请求失败']);
        }
        $ret = $this->toArray($curl_res);
        $this->wxResponse = $ret;
        $this->log->info($ret, '分账申请接口返回值');
        $responseSign = $ret['sign'] ?? '';
        if(!$responseSign) {
            return false;
        }
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info([
            '本地签名' => $localSign,
            '返回值签名' => $responseSign
        ], '签名对比');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS' && !in_array($ret['err_code'], ['ORDER_NOT_READY', 'FREQUENCY_LIMITED'])) {
            throw new Exception($ret['err_code_des']);
        }
        if($ret['result_code'] != 'SUCCESS' && in_array($ret['err_code'], ['ORDER_NOT_READY', 'FREQUENCY_LIMITED'])){
            sleep(1);
            $ret = $this->profitSharingApply($receivers, $profitSharingSn, $transactionId);
            if($ret) {
                return true;
            }
        }
        return true;
    }

    public function profitSharingQuery($profitSharingSn, $transactionId): bool
    {
        $postArr = array(
            'mch_id'=>$this->config['sub_mch_id'],
            'transaction_id'=> $transactionId,
            'out_order_no'=> $profitSharingSn,
            'nonce_str'=>md5($profitSharingSn . time() . rand(1000, 9999)),
        );
        $sign = $this->sign->getSign($postArr, 'HMAC-SHA256', $this->config['md5_key']);
        $postArr['sign'] = $sign;
        $this->log->info($postArr, '分账查询接口入参');
        //2.发送请求
        $url = 'https://api.mch.weixin.qq.com/pay/profitsharingquery';
        $postXML = $this->toXml($postArr);
        $curl_res = $this->curl->post($url,$postXML);
        $ret = $this->toArray($curl_res);
        $this->wxResponse = $ret;
        $this->log->info($ret, '分账结果查询接口返回值');
        $responseSign = $ret['sign'] ?? '';
        if(!$responseSign) {
            return false;
        }
        unset($ret['sign']);
        $signValues = $ret;
        $localSign = $this->sign->getSign($signValues, 'HMAC-SHA256', $this->config['md5_key']);
        $this->log->info([
            '本地签名' => $localSign,
            '返回值签名' => $responseSign
        ], '签名对比');
        if($localSign !== $responseSign) {
            throw new BaseException(['msg' => '微信接口返回数据签名不合法', 'code' => -10]);
        }
        if($ret['return_code'] != 'SUCCESS') {
            throw new Exception($ret['return_msg']);
        }
        if($ret['result_code'] != 'SUCCESS') {
            throw new Exception($ret['err_code_des']);
        }
        if($ret['result_code'] == 'SUCCESS') {
            if($ret['status'] == 'CLOSED'){
                throw new Exception($ret['close_reason']);
            }
            if($ret['status'] != 'FINISHED') {
                sleep(5);
                $ret = $this->profitSharingQuery($profitSharingSn, $transactionId);
                if($ret) {
                    return true;
                }
            }
        }
        return true;
    }
    

}